﻿using BarrageGameAssistant.Core.Configs;
using BarrageGameAssistant.Core.Model;
using ImageProcess;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Reflection.Metadata;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using Win32Proxy.Api;
using Win32Proxy.Helper;
using Win32Proxy.Structs;
using WinCapturer;
using static System.Net.Mime.MediaTypeNames;

namespace BarrageGameAssistant.Core.Extensions
{
    public static class GameProjectExtension
    {
        /// <summary>
        /// 获取游戏进程的句柄
        /// </summary>
        /// <param name="game"></param>
        /// <returns></returns>
        public static IntPtr GetGameHandle(this GameProject game)
        {
            game.Handle = Win32Proxy.Helper.WindowHelper.GetWindowHandleByName(game.ProcessName);
            return game.Handle;
        }

        /// <summary>
        /// 游戏是否运行中
        /// </summary>
        /// <param name="game"></param>
        /// <returns></returns>
        public static bool IsRunning(this GameProject game)
        {
            game.Handle = Win32Proxy.Helper.WindowHelper.GetWindowHandleByName(game.ProcessName);
            return game.Handle != IntPtr.Zero;
        }

        #region 窗体设置
        /// <summary>
        /// 自动设置游戏到最前端
        /// </summary>
        /// <param name="game"></param>
        public static void SetAutoGameForeground(this GameProject game, bool? setForeground = null)
        {
            if (setForeground != null && setForeground.Value)
            {
                Win32Proxy.Api.User32.SetForegroundWindow(game.Handle);
            }
            else
            {
                if (game.AutoGameForeground)
                {
                    Win32Proxy.Api.User32.SetForegroundWindow(game.Handle);
                }
            }
        }

        /// <summary>
        /// 自动聚焦游戏窗体
        /// </summary>
        /// <param name="game"></param>
        /// <param name="setFocus"></param>
        public static void SetAutoGameFocus(this GameProject game, bool? setFocus = null)
        {
            if (setFocus != null && setFocus.Value)
            {
                Win32Proxy.Api.User32.SetFocus(game.Handle);
            }
            else 
            {
                if (game.AutoGameFocus)
                {
                    Win32Proxy.Api.User32.SetFocus(game.Handle);
                }
            }
        }

        /// <summary>
        /// 自动游戏窗体为正常化
        /// </summary>
        /// <param name="game"></param>
        /// <param name="setNormal"></param>
        public static void SetAutoGameWindowNormal(this GameProject game, bool? setNormal = null)
        {
            if (setNormal != null && setNormal.Value)
            {
                Win32Proxy.Helper.WindowHelper.Normal(game.Handle);
            }
            else
            {
                if (game.AutoGameWindowNormal)
                {
                    Win32Proxy.Helper.WindowHelper.Normal(game.Handle);
                }
            }
            
        }
        #endregion

        #region 获取和设置窗体大小、位置、置顶
        /// <summary>
        /// 获取游戏程序的边界
        /// </summary>
        /// <param name="game"></param>
        /// <returns></returns>
        public static System.Drawing.Rectangle GetGameBounds(this GameProject game)
        {
            return Win32Proxy.Helper.WindowHelper.GetWindowBounds(game.Handle);
        }

        /// <summary>
        /// 设置游戏程序的位置和边界
        /// </summary>
        /// <param name="game"></param>
        public static void SetGameBounds(this GameProject game, System.Drawing.Size size, bool? isTop = null)
        {
            System.Drawing.Rectangle windowsRect = Win32Proxy.Helper.WindowHelper.GetWindowBounds(game.Handle, false);
            Screen screen = Screen.FromHandle(game.Handle);
            var screenRect = MonitorHelper.GetScreenResolution(screen.DeviceName);
            bool isLandscape = screen.Bounds.Width > screen.Bounds.Height; //判断宽屏和竖屏 true 宽屏 false 竖屏
            if (!screen.Primary && !isLandscape) //副屏 且 竖放时，直接最大化
            {
                WindowHelper.Maximize(game.Handle);
            }
            else
            {
                System.Drawing.Point _location;
                System.Drawing.Size _size;

                if (game.AutoChangeGameSize)
                {
                    _size = size;
                }
                else
                {
                    _size = windowsRect.Size;
                }

                if (game.AutoChangeGameLocation)
                {
                    int x = screenRect.Width - game.WindowsSetLocation.X - windowsRect.Width;
                    _location = new System.Drawing.Point(x, game.WindowsSetLocation.Y);
                    Win32Proxy.Helper.WindowHelper.SetWindowBounds(game.Handle, _location, _size, game.WindowSetFixWidth, game.WindowSetFixHeigh, game.WindowSetOffsetX, game.WindowSetOffsetY, isTop == null ? game.AutoGameTop : isTop.Value);
                }
                else
                {
                    _location = windowsRect.Location;
                    Win32Proxy.Helper.WindowHelper.SetWindowBounds(game.Handle, _location, _size, game.WindowSetFixWidth, game.WindowSetFixHeigh, game.WindowSetOffsetX, game.WindowSetOffsetY, isTop == null ? game.AutoGameTop : isTop.Value);
                }
                
            }
            
        }
        #endregion

        /// <summary>
        /// 游戏截图
        /// </summary>
        /// <param name="game"></param>
        /// <param name="width">最大宽度</param>
        /// <returns></returns>
        public static System.Drawing.Image? Capture(this GameProject game, int width = 1080)
        {
            IntPtr handle = game.GetGameHandle();
            if (handle == IntPtr.Zero) return null;

            PrintCaptureHelper capture = new();
            capture.Init(handle);
            var image = GetCropImage(game, capture.Capture());
            capture.Cleanup();
            GC.Collect();
            if (game.AutoThumbnail && image?.Width > width)
                return ImageProcess.ImageHelper.Resize(image, width, 0, "W");
            else
                return image;
           
        }

        /// <summary>
        /// 裁剪图片
        /// </summary>
        /// <param name="game"></param>
        /// <param name="bitmapPtr"></param>
        /// <returns></returns>
        private static System.Drawing.Bitmap? GetCropImage(GameProject game, IntPtr bitmapPtr)
        {
            var newImage = System.Drawing.Image.FromHbitmap(bitmapPtr);
            if (game.IsCropImage && game.CropImageSize != System.Drawing.Size.Empty)
            {
                var cropImg = ImageHelper.Crop(newImage, new System.Drawing.Rectangle(game.CropImageLocation, game.CropImageSize));
                newImage.Dispose();
                return cropImg;
            }
            else
            {
                return newImage;
            }
        }

        /// <summary>
        /// 判断裁剪和缩略
        /// </summary>
        /// <param name="game"></param>
        /// <param name="newImage"></param>
        /// <param name="width"></param>
        /// <returns></returns>
        public static System.Drawing.Bitmap? GetImage(this GameProject game, System.Drawing.Image newImage, int width = 1080)
        {
            if (game.IsCropImage && game.CropImageSize != System.Drawing.Size.Empty)
            {
                var cropImg = ImageHelper.Crop((System.Drawing.Bitmap)newImage, new System.Drawing.Rectangle(game.CropImageLocation, game.CropImageSize));
                newImage.Dispose();
                if (game.AutoThumbnail && cropImg?.Width > width)
                    return ImageProcess.ImageHelper.Resize(cropImg, width, 0, "W") as System.Drawing.Bitmap;
                else
                    return cropImg;
            }
            else
            {
                if (game.AutoThumbnail && newImage?.Width > width)
                    return ImageProcess.ImageHelper.Resize((System.Drawing.Bitmap)newImage, width, 0, "W") as System.Drawing.Bitmap;
                else
                    return newImage as System.Drawing.Bitmap;
            }
        }
    }

}
